package com.checksound;

import java.util.ArrayList;
import java.util.List;

import org.achartengine.ChartFactory;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Paint.Align;

/**
 * Draws a line chart.
 * 
 * Based on XYChartBuilder.java from aChartEngine http://www.achartengine.org/ (Apache License, Version 2.0).
 * 
 */

public class LineChart {

	//the x-values for the graph
	double[] xValues;
	 
	//the y-values for the graph
	double[] yValues;
	 
	// the base frequency
	double fBase;
	double xMax;
	
	//the chart title
	String title;
	
	//color of the chart line & fill underneath
	int chartLineColor = Color.parseColor("#7A5DC7" /*"#9E7BFF #8D38C9"*/);

	 /**
	   * Constructor.
	   * 
	   * @param double[] xValues The x-values for the graph
	   * @param double[] yValues The y-values for the graph
	   * @param String xAxisLabel The x-axis title
	   * @param String xAxisLabel The y-axis title
	   * @param String title The chart title
	   * @param double[] chartLimits An array containing the parameters for the chart size: {min x, max x, min y, max y}
	   * @param double[] panLimits An array containing the parameters for the "pan limits", how far the user can shift the graph:
	   *   {min x, max x, min y, max y}
	   * @param double[] zoomLimits An array containing the parameters for the "zoom limits", how far the user can zoom the graph:
	   *   {min x, max x, min y, max y}
	   */
	 
	  public LineChart(double[] xValues, double[] yValues, String title, double fBase)
	  {
		  this.xValues = xValues;
		  this.yValues = yValues;
		  this.fBase = fBase;
		  final int n = xValues.length;
		  
		  this.xMax = fBase * 3.5;
		  if( this.xMax == 0 || this.xMax > xValues[n-1])
			  this.xMax = xValues[n-1];

		  double maxval = 0;
		  for( int i=0; i<n; ++i )
			  if( yValues[i] > maxval )
				  maxval = yValues[i];
		  for( int i=0; i<n; ++i )
			  this.yValues[i] = Math.log10(yValues[i]/maxval*1e6+1) * 10.0;		  
		  
		  this.title = title;
	  }

	  /**
	   * Executes the chart demo.
	   * 
	   * @param context the context
	   * @return the built intent
	   */
	  public Intent execute(Context context) {
	    String[] titles = new String[] { "" };
	    List<double[]> x = new ArrayList<double[]>();
	    x.add(xValues);
	    List<double[]> values = new ArrayList<double[]>();
	    values.add(yValues);
	    int[] colors = new int[] {chartLineColor};
	    PointStyle[] styles = new PointStyle[] { PointStyle.POINT};
	    XYMultipleSeriesRenderer renderer = buildRenderer(colors, styles);
	    int length = renderer.getSeriesRendererCount();
	    for (int i = 0; i < length; i++) {
	      XYSeriesRenderer seriesRenderer = (XYSeriesRenderer) renderer.getSeriesRendererAt(i);
	      seriesRenderer.setFillPoints(true);
	      seriesRenderer.setFillBelowLine(true);
	      seriesRenderer.setFillBelowLineColor(chartLineColor);
	    }
	    setChartSettings(renderer, "", "Hz", "dB", 0, xMax, 0, 60,
	        Color.LTGRAY, Color.LTGRAY, context);
	    renderer.setXLabels(12);
	    renderer.setYLabels(10);
	    renderer.setShowGrid(true);
	    renderer.setXLabelsAlign(Align.RIGHT);
	    renderer.setYLabelsAlign(Align.RIGHT);
	    renderer.setZoomButtonsVisible(true);
	    final double limits[] = {0, xValues[xValues.length-1], 0, 60};
	    renderer.setPanLimits(limits);
	    renderer.setZoomLimits(limits);
	    renderer.setShowLegend(false);
	    Intent intent = ChartFactory.getCubicLineChartIntent(context, buildDataset(titles, x, values),
	        renderer, 0.33f, title);
	    return intent;
	  }


	  /**
	   * Builds an XY multiple dataset using the provided values.
	   * 
	   * @param titles the series titles
	   * @param xValues the values for the X axis
	   * @param yValues the values for the Y axis
	   * @return the XY multiple dataset
	   */
	  protected XYMultipleSeriesDataset buildDataset(String[] titles, List<double[]> xValues,
	      List<double[]> yValues) {
	    XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
	    addXYSeries(dataset, titles, xValues, yValues, 0);
	    return dataset;
	  }

	  public void addXYSeries(XYMultipleSeriesDataset dataset, String[] titles, List<double[]> xValues,
	      List<double[]> yValues, int scale) {
	    int length = titles.length;
	    for (int i = 0; i < length; i++) {
	      XYSeries series = new XYSeries(titles[i], scale);
	      double[] xV = xValues.get(i);
	      double[] yV = yValues.get(i);
	      int seriesLength = xV.length;
	      for (int k = 0; k < seriesLength; k++) {
	        series.add(xV[k], yV[k]);
	      }
	      dataset.addSeries(series);
	    }
	  }

	  /**
	   * Builds an XY multiple series renderer.
	   * 
	   * @param colors the series rendering colors
	   * @param styles the series point styles
	   * @return the XY multiple series renderers
	   */
	  protected XYMultipleSeriesRenderer buildRenderer(int[] colors, PointStyle[] styles) {
	    XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
	    setRenderer(renderer, colors, styles);
	    return renderer;
	  }

	  protected void setRenderer(XYMultipleSeriesRenderer renderer, int[] colors, PointStyle[] styles) {
	    renderer.setAxisTitleTextSize(16);
	    renderer.setChartTitleTextSize(20);
	    renderer.setLabelsTextSize(15);
	    renderer.setLegendTextSize(15);
	    renderer.setPointSize(5f);
	    renderer.setMargins(new int[] { 20, 30, 15, 20 });
	    int length = colors.length;
	    for (int i = 0; i < length; i++) {
	      XYSeriesRenderer r = new XYSeriesRenderer();
	      r.setColor(colors[i]);
	      r.setPointStyle(styles[i]);
	      renderer.addSeriesRenderer(r);
	    }
	  }

	  /**
	   * Sets a few of the series renderer settings.
	   * 
	   * @param renderer the renderer to set the properties to
	   * @param title the chart title
	   * @param xTitle the title for the X axis
	   * @param yTitle the title for the Y axis
	   * @param xMin the minimum value on the X axis
	   * @param xMax the maximum value on the X axis
	   * @param yMin the minimum value on the Y axis
	   * @param yMax the maximum value on the Y axis
	   * @param axesColor the axes color
	   * @param labelsColor the labels color
	   */
	  protected void setChartSettings(XYMultipleSeriesRenderer renderer, String title, String xTitle,
	      String yTitle, double xMin, double xMax, double yMin, double yMax, int axesColor,
	      int labelsColor, Context context) {
	    renderer.setChartTitle(title);
	    renderer.setXTitle(xTitle);
	    renderer.setYTitle(yTitle);
	    renderer.setXAxisMin(xMin);
	    renderer.setXAxisMax(xMax);
	    renderer.setYAxisMin(yMin);
	    renderer.setYAxisMax(yMax);
	    renderer.setAxesColor(axesColor);
	    renderer.setLabelsColor(labelsColor);
	    
	    //scale the text size according to the density of the screen
	    float scale = context.getResources().getDisplayMetrics().density;
	    renderer.setLabelsTextSize((10.0f * scale + 0.5f));
	    renderer.setAxisTitleTextSize((10.0f * scale + 0.5f));
	  }
  
}